package com.roncoo.example;

import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import java.util.stream.Stream;
import org.apache.commons.crypto.random.CryptoRandom;
import org.apache.commons.crypto.random.CryptoRandomFactory;

/**
 * Example showing use of the CryptoRandom API
 */
public class RandomExample {

  public static void main(String[] args) throws GeneralSecurityException, IOException {

    String productList = "2040=ES脱敏,1010=数据库审计";

    for (String s : productList.split(",")) {
      System.out.println(s.split("\\=")[0]);
      System.out.println(s.split("\\=")[1]);
    }

// 1. Individual values
    Stream stream = Stream.of("a", "b", "c");
// 2. Arrays
    String[] strArray = new String[]{"a", "b", "c"};
    stream = Stream.of(strArray);
    stream = Arrays.stream(strArray);
// 3. Collections
    List<String> list = Arrays.asList(strArray);
    stream = list.stream();
    // Constructs a byte array to store random data.
    byte[] key = new byte[16];
    byte[] iv = new byte[32];

    Properties properties = new Properties();
    properties.put(CryptoRandomFactory.CLASSES_KEY,
        CryptoRandomFactory.RandomProvider.OPENSSL.getClassName());

    // Gets the 'CryptoRandom' instance.
    try (CryptoRandom random = CryptoRandomFactory.getCryptoRandom(properties)) {

      // Show the actual class (may be different from the one requested)
      System.out.println(random.getClass().getCanonicalName());

      // Generate random bytes and places them into the byte arrays.
      random.nextBytes(key);
      random.nextBytes(iv);

    }

    // Show the generated output
    System.out.println(Arrays.toString(key));
    System.out.println(Arrays.toString(iv));


  }

  public static void asynExeLocalComand(File file, String... command) throws IOException {
// 不使用Runtime.getRuntime().exec(command)的方式,因为无法设置以下特性
// Java执行本地命令是启用一个子进程处理,默认情况下子进程与父进程I/O通过管道相连(默认ProcessBuilder.Redirect.PIPE)
// 当服务执行自身重启的命令时,父进程关闭导致管道连接中断,将导致子进程也崩溃,从而无法完成后续的启动
// 解决方式,(1)设置子进程IO输出重定向到指定文件;(2)设置属性子进程的I/O源或目标将与当前进程的相同,两者相互独立
    ProcessBuilder pb = new ProcessBuilder(command);
    if (file == null || !file.exists()) {
// 设置属性子进程的I/O源或目标将与当前进程的相同,两者相互独立
      pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
      pb.redirectError(ProcessBuilder.Redirect.INHERIT);
      pb.redirectInput(ProcessBuilder.Redirect.INHERIT);
    } else {
// 设置子进程IO输出重定向到指定文件
// 错误输出与标准输出,输出到一块
      pb.redirectErrorStream(true);
// 设置输出日志
      pb.redirectOutput(Redirect.appendTo(file));
    }
// 执行命令进程
    pb.start();
  }

}
